﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using RestSharp;

namespace Nuget本地升级46
{
   public static class ext
    {
        public static Task DownloadDataByProgress(this IRestClient rc,IRestRequest req,string file,IProgress<DownloadDataStruct> progress )
        {
            return Task.Run(() =>
            {
                var finalFileSize = rc.Head(req).ContentLength;
                req.Method = Method.GET;
                DownloadDataStruct data = new DownloadDataStruct();
                data.FinalFileSize = finalFileSize;
                using (var writer = new HikFileStream(file))
                {
                    writer.Progress += (w, arg) => {
                        
                        data.CurrentSize = writer.CurrentSize;
                        progress.Report(data);
                    };
                    req.ResponseWriter = responseStream => responseStream.CopyTo(writer);
                    rc.DownloadData(req);
                }

            });
        }
        public interface IProgress<T>
        {
            void Report(T data);
        }
        public class Progress<T> : IProgress<T>
        {
            readonly SynchronizationContext _context;
            public Progress()
            {
                _context = SynchronizationContext.Current
                    ?? new SynchronizationContext();
            }

            public Progress(Action<T> action)
                : this()
            {
                ProgressReported += action;
            }

            public event Action<T> ProgressReported;

            void IProgress<T>.Report(T data)
            {
                var action = ProgressReported;
                if (action != null)
                {
                    _context.Post(arg => action((T)arg), data);
                }
            }
        }

        public struct DownloadDataStruct
        {
            public long CurrentSize { get; set; }
            public long FinalFileSize { get; set; }
        }

        class HikFileStream : FileStream
        {
            public HikFileStream(string path) : base(path, FileMode.Create, FileAccess.Write, FileShare.None)
            {
            }

            public long CurrentSize { get; private set; }


            public event EventHandler Progress;

            public override void Write(byte[] array, int offset, int count)
            {
                base.Write(array, offset, count);
                CurrentSize += count;
                var h = Progress;
                h?.Invoke(this, EventArgs.Empty);//WARN: THIS SHOULD RETURNS ASAP!
            }

        }

    }
}
